"use client";
import AddNodes from '@/app/ui/flowise/add-nodes';
import ButtonEdge from '@/app/ui/flowise/button-edge';
import CanvasHeader from '@/app/ui/flowise/canvas-header';
import CustomNode from '@/app/ui/flowise/custom-node';
import ShowMessage from '@/app/ui/flowise/show-message';
import useReactflowStore from '@/lib/store/useReactflowStore';
import { getUniqueNodeId, initNode } from '@/lib/utils/help';
import { getChatFlowInfo } from '@/server/flowise/data';
import { useCallback, useEffect, useRef, useState } from 'react';
import ReactFlow, {
    MiniMap,
    Controls,
    Background,
    useNodesState,
    useEdgesState,
    addEdge,
    Connection,
    Edge,
    ReactFlowProvider,
} from 'reactflow';

import 'reactflow/dist/style.css';

const nodeTypes = { customNode: CustomNode }
const edgeTypes = { buttonedge: ButtonEdge }

// const initialEdges = [
//     {
//         id: 'e1-2',
//         source: '1',
//         target: '2',
//         style: { stroke: '#f6ab6c' }, // 连接线颜色
//         animated: true,
//         labelStyle: { fill: '#f6ab6c', fontWeight: 700 }, // 连接线名称样式
//         markerEnd: { // 连接线尾部的箭头
//             type: MarkerType.ArrowClosed,
//             color: '#4E8FF0',
//         }
//     }
// ];

export default function CanvasPage({ params }: any) {
    const [nodes, setNodes, onNodesChange] = useNodesState([]);
    const [edges, setEdges, onEdgesChange] = useEdgesState([]);
    const [viewport, setViewport] = useState({});
    const [detailInfo, setDetailInfo] = useState(null);
    const reactFlowWrapper = useRef(null);
    const { reactFlowInstance, setReactFlowInstance } = useReactflowStore();

    useEffect(() => {
        const id = params?.id?.[0];
        if (!id) return;
        getChatFlowInfo(id).then(res => {
            const flowData = JSON.parse(res.flowData);
            const nodes = flowData.nodes.map((node: any) => ({
                ...node,
                data: { ...node.data, forceToolbarVisible: true }
            }))
            setDetailInfo(res);
            setNodes(nodes);
            setEdges(flowData.edges);
            setViewport(flowData.viewport);
            // console.log(flowData);
        });
    }, [params?.id]);

    useEffect(() => {
        reactFlowInstance?.setViewport(viewport as any)
    }, [reactFlowInstance, viewport]);

    const onConnect = useCallback((params: Edge | Connection) => {
        const newEdge = {
            ...params,
            type: 'buttonedge',
            id: `${params.source}-${params.sourceHandle}-${params.target}-${params.targetHandle}`
        }
        setEdges((eds) => addEdge(newEdge, eds))
    }, [setEdges]);

    const onDragOver = useCallback((event: any) => {
        event.preventDefault()
        event.dataTransfer.dropEffect = 'move'
    }, [])

    const onDrop = useCallback((event: any) => {
        event.preventDefault();
        let nodeData = event.dataTransfer.getData('application/reactflow');
        // check if the dropped element is valid
        if (typeof nodeData === 'undefined' || !nodeData) {
            return
        }

        nodeData = JSON.parse(nodeData);
        const reactFlowBounds = (reactFlowWrapper.current as any)?.getBoundingClientRect();
        const position = reactFlowInstance?.screenToFlowPosition({
            x: event.clientX - reactFlowBounds.left - 100,
            y: event.clientY - reactFlowBounds.top - 50
        });
        const newNodeId = getUniqueNodeId(nodeData, reactFlowInstance?.getNodes() || [])

        const newNode = {
            id: newNodeId,
            position,
            type: 'customNode',
            data: initNode(nodeData, newNodeId)
        }
        setNodes((nds: any[]) =>
            nds.concat(newNode).map((node) => {
                if (node.id === newNode.id) {
                    node.data = {
                        ...node.data,
                        selected: true
                    }
                } else {
                    node.data = {
                        ...node.data,
                        selected: false
                    }
                }

                return node
            })
        )
    }, [reactFlowInstance]);

    return (
        <div className='h-screen flex flex-col'>
            <CanvasHeader data={detailInfo} />
            <div className='flex-1 h-full relative' ref={reactFlowWrapper}>
                <div className='absolute left-5 top-5 z-50 flex rounded-full'>
                    <AddNodes />
                </div>
                <div className='absolute right-5 top-5 z-50 flex rounded-full'>
                    <ShowMessage />
                </div>
                <ReactFlowProvider>
                    <ReactFlow
                        nodes={nodes} // 节点
                        edges={edges} // 连接线
                        nodeTypes={nodeTypes} // 自定义
                        edgeTypes={edgeTypes} // 自定义
                        onNodesChange={onNodesChange} // 节点拖拽等改变
                        onEdgesChange={onEdgesChange} // 连接线拖拽等改变
                        onConnect={onConnect} // 节点直接连接
                        onDrop={onDrop}
                        onDragOver={onDragOver}
                        onInit={setReactFlowInstance}
                        fitView // 渲染节点数据
                        preventScrolling={true}
                        attributionPosition="bottom-right" // react-flow的位置,类似水印,可以通过css隐藏
                    >
                        <MiniMap style={{ scale: 1 }} />
                        <Controls
                            style={{
                                display: 'flex',
                                flexDirection: 'row',
                                left: '50%',
                                transform: 'translate(-50%, -50%)'
                            }}
                        />
                        <Background color='#aaa' gap={16} />
                    </ReactFlow>
                </ReactFlowProvider>
            </div>
        </div>
    );
}